package com.study.example.gameserver.module.ranklist.handler.impl;

import com.sparrow.common.ranklist.RankElement;
import com.sparrow.common.thread.IdExecutorGroup;
import com.sparrow.common.util.JsonUtil;
import com.sparrow.common.util.TimeUtil;
import com.sparrow.event.annotation.EventReceiver;
import com.sparrow.example_message.rank.vo.RankVo;
import com.study.example.gameserver.module.player.entity.Player;
import com.study.example.gameserver.module.player.event.PlayerExpChangeEvent;
import com.study.example.gameserver.module.ranklist.RankService;
import com.study.example.gameserver.module.ranklist.domain.RankType;
import com.study.example.gameserver.module.ranklist.entity.PlayerRank;
import com.study.example.gameserver.module.ranklist.handler.RankHandler;
import com.study.example.gameserver.module.ranklist.handler.data.LevelRankData;
import com.study.example.gameserver.module.ranklist.manager.RankManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 等级排行榜处理器
 */
@Component
public class LevelRankHandler extends RankHandler<LevelRankData> {

    @Autowired
    RankManager rankManager;

    @Override
    public RankType getHandlerKey() {
        return RankType.LEVEL;
    }

    @Autowired
    IdExecutorGroup idExecutorGroup;

    @Autowired
    RankService rankService;
    /**
     * 玩家升级事件
     */
    @EventReceiver
    public void onExpChange(PlayerExpChangeEvent event) {
        Player player = event.getPlayer();
        rankService.updateRank(getHandlerKey(), player, (rankType, p) -> {
            LevelRankData rankData = new LevelRankData();
            rankData.setLevel(player.getLevel());
            rankData.setExp(player.getExp());
            rankData.setTime(TimeUtil.currentTimeMillis());
            return rankData;
        });
    }

    @Override
    public LevelRankData decode(String rankDataStr) {
        return JsonUtil.parse(rankDataStr, LevelRankData.class);
    }

    @Override
    public String encode(LevelRankData data) {
        return JsonUtil.toJSON(data);
    }

    @Override
    public int compare(Object a, Object b) {
        LevelRankData x = (LevelRankData) a;
        LevelRankData y = (LevelRankData) b;
        // 等级降序
        int cmp = Integer.compare(y.getLevel(), x.getLevel());
        if (cmp != 0) {
            return cmp;
        }
        // 经验值降序
        cmp = Integer.compare(y.getExp(), x.getExp());
        if (cmp != 0) {
            return cmp;
        }
        // 达成时间升序（越早越靠前）
        return Long.compare(x.getTime(), y.getTime());
    }

    @Override
    protected void fillRankVo(RankElement e, RankVo rankVo) {
        PlayerRank playerRank = rankManager.getOrCreateRank(getHandlerKey(), e.getRankElementId());
        LevelRankData rankData = (LevelRankData) playerRank.getRankData();
        rankVo.setPlayerName(playerRank.getPlayerName());
        rankVo.setRankValue(rankData.getLevel());
    }

}
